package peace.htmllooker
{
import flash.text.StyleSheet;

import peace.htmllooker.node.Text;
import peace.htmllooker.node.table.Table;

import peace.data.Constraints;
import peace.gui.layout.ColumnLayout;
	
/**
 * Базовый контейнер с вертикальным рендерингом произвольных html-элементов 
 */
public class VerticalHtmlBox extends Box
{
	/**
	 * 
	 * @param xml
	 * @param css
	 * 
	 */	
	public function VerticalHtmlBox (xml:XML, css:StyleSheet)
	{
		super(xml, css);
	}
	/**
	 * 
	 * @param xml
	 * @param css
	 * 
	 */
	override protected function init(xml:XML, css:StyleSheet):void
	{
		container.layout = new ColumnLayout (new Constraints(), 0, align, valign);

		super.init(xml, css);
	}
	/**
	 * 
	 * 
	 */	
	override public function arrange():void
	{
		if (! needArrange) return;
		// обнуляем размеры
		minWidth = minHeight = preferredWidth = preferredHeight = 0;
		
		// рекурсивно выравниваем детей
		var n:Node;
		for each (n in container.children)
		{
			// выравнивать Node смысла нет, 
			// при изменении размеров Node выравнивается немедленно 
			if (n is Box)
			{
				n.arrange();
			}
			// обновляем размеры
			minWidth = Math.max(minWidth, n.minWidth);
			minHeight += n.minHeight;
			preferredWidth = Math.max(preferredWidth, n.preferredWidth);
			preferredHeight += n.preferredHeight;
		}
		minWidth += shellWidth;
		preferredWidth += shellWidth;
		minHeight += shellHeight;
		preferredHeight += shellHeight;
		
		container.arrange();

		needArrange = false;

		super.arrange();
	}
	/**
	 * 
	 * @param xml
	 * @param css
	 * 
	 */	
	override protected function createChildren(xml:XML, css:StyleSheet):void
	{
		var nodeFactory:NodeFactory = Htmllooker.nodeFactory;
		
		var cache:XML = <html/>; // кешируем немодульные узлы в один текстовый, оптимальнее бля	
		for each (var n:XML in xml.*)
		{
			if (nodeFactory.has(n.localName()))
			{
				if (cache.*.length() > 0)
				{
					container.add (new Text(cache, css));
					// чистим кеш
					delete cache.*;
				}
				
				container.add (nodeFactory.getNode(n, css));
				
			}
			else
			{
				cache.* += n;
			}
		}
		if (cache.*.length() > 0)
		{
			container.add (new Text(cache, css));
		}
	}
	/**
	 * 
	 * @param value
	 * 
	 */
	override public function set width(value:Number):void
	{
		if (value == container.userWidth + shellWidth) return;
		
		applyWidth(value - shellWidth);
		
		super.width = value;
	}
	/**
	 * 
	 * @param value
	 * 
	 */	
	override public function set height(value:Number):void
	{
		if (value == container.userHeight + shellHeight) return;
		
		applyHeight (value - shellHeight)
		
		super.height = value;
	}
	/**
	 * Применяем высоту бокса к дочерним узлам
	 *  
	 * @param value Number
	 * 
	 */	
	protected function applyWidth (value:Number):void
	{
		var n:Node;
		for each (n in container.children)
		{
			n.width = value;
		}
	}
	/**
	 * Применяем высоту бокса к дочерним узлам
	 *  
	 * @param value Number
	 * 
	 */	
	protected function applyHeight (value:Number):void
	{
		// Практически неебущий фактор.
		// Интересен только в случае таблиц, размер которых указан в процентах:
		// ищем такие и делим остаточный размер пропорционально

		var n:Node;
		// сумма высот детей, которые не явл таблицами с процентной высотой
		var realHeight:Number = 0;
		// дети-таблицы с процентной высотой
		var tables:Array = [];
		// сумма процентов высоты в таблицах
		var tablesPercentHeightSum:Number = 0;
		
		for each (n in container.children)
		{
			if (n is Table && n.percentHeight)
			{
				tables.push(n);
				tablesPercentHeightSum += n.percentHeight;
			}
			else
			{
				realHeight += n.height;
			}
		}
		
		var pHeight:Number = value - realHeight;
		// если запаса высоты нет, то актуальны только реальные размеры таблиц
		if (pHeight <= 0) return;

		for each (n in tables)
		{
			// таблицам с процентной высотой выставляем минимальную между
			// - реальными процентами от высоты бокса
			// - пропорциональными процентами от остаточной высоты для таблиц (с процентной высотой)
			Table(n).height = Math.min (value * n.percentHeight/100, pHeight * n.percentHeight/tablesPercentHeightSum); 
		}
	}
	
}
}